//数组转树结构
function arrayToTree(arr,op={}){
  const option=Object.assign({
    ch:'children',
    id:'id',pid:'pid'
  },op);
  const map=arr.reduce((prev,curr,idx,arr) => {
    prev[curr[option.id]]=curr;
    return prev;
  },{});
  const result=[];
  arr.map(item => {
    if(item[option.pid] in map){
      let parent=map[item[option.pid]];
      parent[option.ch]=parent[option.ch]||[];
      parent[option.ch].push(item);
    }else{
      result.push(item);
    }
  });
  return result;
}

//树结构转数组
function treeToArray(tree,op={}){
  const option=Object.assign({
    ch:'children'
  },op);
  const result=[...tree];
  for(let i=0;i<result.length;i++){
    if(!result[i][option.ch]) continue;
    result.splice(i+1,0,...result[i][option.ch]);
  }
  result.map(item => delete item[option.ch]);
  return result;
}

//遍历树结构
function treeForeach(tree,cb,op={}){
  const option=Object.assign({
    ch:'children'
  },op);
  let queue=[...tree],node=null;
  while(node=queue.shift()){
    cb(node);
    node[option.ch]&&queue.unshift(...node[option.ch]);
  }
}

//查找节点
function treeFind(tree,cb,op={}){
  const option=Object.assign({
    ch:'children'
  },op);
  for(const item of tree){
    if(cb(item)) return item;
    if(item[option.ch]){
      return treeFind(item[option.ch],cb,op);
    }
  }
  return null;
}

//查找节点路径
function treeFindPath(tree,cb,op={}){
  const option=Object.assign({
    ch:'children'
  },op);
  let path=[];
  for(const item of tree){
    path.push(item);
    if(cb(item)) return path;
    if(item[option.ch]){
      let chPath=treeFindPath(item[option.ch],cb,op);
      path.push(...chPath);
      if(chPath.length) return path;
    }
    path.pop();
  }
  return path;
}

export {
  arrayToTree,treeToArray,treeForeach,treeFind,treeFindPath
}